package cn.thoughtworks.school.services;

import cn.thoughtworks.school.exceptions.BusinessException;
import cn.thoughtworks.school.feign.ProgramCenterFeign;
import cn.thoughtworks.school.utils.Encrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class ProgramService {
    @Autowired
    private ProgramCenterFeign programCenterFeign;

    public void dealProgram(String code, Long id) throws BusinessException {
        String[] registerInfo = getRegisterInfo(code);
        String type = registerInfo[0];
        String programId = registerInfo[1];
        if (needToJoinProgram(type, programId)) {
            joinProgram(type, programId, id);
        }
    }

    public void joinProgram(String type, String programId,Long userId) {
        Map data = new HashMap();
        data.put("programId", programId);
        data.put("tutorId", userId);
        data.put("userId", userId);
        programCenterFeign.joinProgram(Long.parseLong(programId), type, userId, data);
    }
    private boolean needToJoinProgram(String TYPE, String PROGRAM) {
        return Objects.nonNull(TYPE) && Objects.nonNull(PROGRAM)
          && (Objects.equals("tutor", TYPE) || Objects.equals("student", TYPE))
          && Integer.parseInt(PROGRAM) > 0;
    }

    //加密算法 hashcode
    //example：(enable=1 or 0 ;  type=student or tutor)
    //前端：code = hashcode(type) +enable+ '.' + hashcode(type+programId+programId)+'.'+programId

    private String[] getRegisterInfo(String code) throws BusinessException {
        if (Objects.isNull(code)) {
            return new String[]{"", "0"};
        }
        String[] typeAndRole = code.split("\\.");
        verify(typeAndRole);
        return getProgramUserRoleAndProgramId(typeAndRole);
    }

    private String[] getProgramUserRoleAndProgramId(String[] data) {
        String type = "student";
        if (isRole("tutor", data[0])) {
            type = "tutor";
        }
        return new String[]{type, data[2]};
    }

    private void verify(String[] data) throws BusinessException {
        if (data.length != 3) {
            throw new BusinessException("params invalid");
        }

        if (!isProgramUserRoleCorrect(data)) {
            throw new BusinessException("params invalid");
        }
        if (!isEnableRegisterEntry(data)) {
            throw new BusinessException("current program is not open");
        }
    }

    private boolean isProgramUserRoleCorrect(String[] data) {
        return isRole("student", data[0])
          ||
          isRole("tutor", data[0]);
    }

    private boolean isRole(String type, String result) {
        return (Encrypt.hashcode(type)+"1")
          .equals(result);
    }

    private boolean isEnableRegisterEntry(String[] data) {
        String[] userRoleAndProgramId = getProgramUserRoleAndProgramId(data);
        Map program = programCenterFeign.getProgramInviteLinks(Long.parseLong(userRoleAndProgramId[1]));

        if ("student".equals(userRoleAndProgramId[0])) {
            return (boolean) program.get("studentLink");
        }
        if ("tutor".equals(userRoleAndProgramId[0])) {
            return (boolean) program.get("tutorLink");
        }
        return false;
    }
}
